import {InterfaceShape} from "@/utils/Shape";
import {getShapeId} from "@/utils/canvasUtil";
import {InterfaceDragShape} from "@/utils/DragShape";
import {Point} from "@/utils/Point";
import {AndShape} from "@/utils/Drawing";

interface OnloadCb {
  (shape: AndShape): void
}

export class CanvasImage implements InterfaceShape, InterfaceDragShape {
  id: string;
  ctx: CanvasRenderingContext2D;
  x: number
  y: number
  width: number
  height: number
  image?: HTMLImageElement
  drawable: boolean
  dragStartPoint: Point | null
  fillStyle: string;

  constructor(ctx: CanvasRenderingContext2D, file: File, onload: OnloadCb) {
    this.id = getShapeId()
    this.ctx = ctx
    this.x = 0
    this.y = 0
    this.width = 0
    this.height = 0
    this.drawable = true
    this.dragStartPoint = null
    this.fillStyle = `rgba(${this.id},1)`

    const url = URL.createObjectURL(new Blob([file]))
    const image = new Image()
    image.onload = () => {
      this.setSize(image.width, image.height)
      this.image = image
      this.draw()
      onload(this)
    }
    image.src = url
  }

  setSize(width: number, height: number) {
    this.width = width
    this.height = height
  }

  draw(ctx?: CanvasRenderingContext2D | string): void {
    if (this.image) {
      this.ctx.drawImage(this.image, this.x, this.y, this.width, this.height)
    }
  }

  playback(): void {
    this.draw()
  }

  drawEventCanvas(ctx: CanvasRenderingContext2D): void {
    ctx.fillStyle = this.fillStyle
    ctx.fillRect(this.x, this.y, this.width, this.height)
  }

  dragStart(x: number, y: number) {
    this.dragStartPoint = new Point(x, y)
    return true
  }

  dragging(x: number, y: number) {
    const {dragStartPoint} = this
    if (dragStartPoint) {
      const translateX = x - dragStartPoint.x
      const translateY = y - dragStartPoint.y

      this.x += translateX
      this.y += translateY

      this.dragStartPoint = new Point(x, y)
      return true
    }
    return false
  }

  dragEnd(x: number, y: number) {
    this.dragStartPoint = null
    return true
  }

}
